#ifndef __SN_CONFIG_H__
#define __SN_CONFIG_H__

#include <sys/types.h>
#include "sn_rbtree.h"
#include "sn_string.h"
#include "sn_mempool.h"
#include "sn_queue.h"

typedef enum   sn_conf_opt_type_e       sn_conf_opt_type_t;
typedef enum   sn_conf_type_e           sn_conf_type_t;
typedef union  sn_conf_value_u          sn_conf_value_t;
typedef struct sn_conf_load_section_s   sn_conf_load_section_t;
typedef struct sn_conf_node_values_s    sn_conf_node_values_t;
typedef struct sn_config_kv_s           sn_config_kv_t;
typedef struct sn_config_section_s      sn_config_section_t;
typedef struct sn_config_s              sn_config_t;

#define PRINT_LEVEL              "\t\t\t\t\t\t\t\t\t\t\t\t"

#define CONF_NODE_KEY_LEN        512
#define CONF_FILE_PATH_LEN       512
#define CONF_NODE_VALUES_CNT     20
#define CONF_FILE_LINE_LEN       512
#define CONF_FILE_LINE_TRIM      " \t\n\r"
#define CONF_FILE_LINE_NOTE      '#'
#define CONF_FILE_INCLUDE_FILE   "include"
#define CONF_FILE_MULT_VALUES    "location"
#define CONF_ROOT_NODE_NAME      "CONF_ROOT_NODE_NAME"

enum sn_conf_opt_type_e{
	CONF_OPT_COMM,
	CONF_OPT_INCL,
	CONF_OPT_LOCA,
	CONF_OPT_INCL_VAL,
	CONF_OPT_LOCA_VAL
};

enum sn_conf_type_e{
	CONF_NODE,
	CONF_LINK
};

union sn_conf_value_u{
	sn_config_section_t    *link;
	sn_conf_node_values_t  *node;
};


struct sn_conf_load_section_s{
	sn_config_section_t *sect;
	sn_queue_t          queue;
};

struct sn_conf_node_values_s{
	int16_t             max;
	int16_t             count;
	u_char              **arr;
};

struct sn_config_kv_s{
	sn_conf_opt_type_t  type;
	u_char              *key;
	u_char              *val;
};

struct sn_config_section_s{
	sn_rbtree_node_t    node;     //该section对应红黑树的节点
	u_char              *name;    //section名称
	sn_config_section_t *next;    //同级的兄弟section
	sn_conf_value_t     value;    //下级section或值
	sn_conf_type_t      type;     //类型
};

struct sn_config_s{
	sn_rbtree_t         *ntree;    //红黑树
	sn_config_section_t *sroot;
	sn_mempool_t        *mpool;
};

sn_config_t * sn_create_config(u_char *file, sn_mempool_t *mpool);
void sn_destory_config(sn_config_t *conf);
void sn_print_config(sn_config_t *conf);
void sn_print_conf_section(sn_config_section_t *sect, int16_t n);
sn_conf_node_values_t * sn_find_conf_node_value(sn_config_t *conf, u_char *sname);
sn_config_section_t * sn_find_conf_section(sn_config_t *conf, u_char *sname);
int32_t sn_load_conf_file(sn_config_section_t *sect, u_char *file, sn_config_t *conf);
int32_t sn_get_conf_line(u_char *src, sn_str_t *up_key, sn_config_kv_t *kv, int16_t *level, sn_mempool_t *mpool);
void sn_conf_section_build(sn_config_section_t *sect, sn_config_t *conf, u_char *val);
void sn_conf_section_insert_val(sn_config_section_t *sect, sn_config_t *conf, void *val);
void sn_conf_free_section(sn_config_section_t *sect);
void sn_conf_free_section_recursion(sn_config_section_t *sect);
void sn_conf_free_section_kv(sn_config_section_t *sect);
void sn_conf_free_loadsect(sn_conf_load_section_t *loadsect);
#endif
